
const http = require('http')
const fs = require('fs/promises')
const path = require('path')
const parse = require('url').parse
const { createReadStream } = require('fs')
const mime = require('mime')
const ejs = require('ejs')
const { promisify } = require('util')


function configMerge(config) {
    return {
        directory: process.cwd(),
        port: 3306,
        ...config
    }
}

module.exports = class Serve {
    constructor(config) {
        this.config = configMerge(config)
    }
    start() {
        let server = http.createServer(this.serverHandle.bind(this))
        const { port } = this.config
        server.listen(port, () => {
            console.log('http://localhost:' + port)
        })
    }
    async serverHandle(req, res) {
        // 1.路径解析
        let { pathname, query } = parse(req.url, true)
        pathname = decodeURIComponent(pathname) // 中文会被编码
        let abPath = path.join(this.config.directory, pathname)
        try {
            let statObj = await fs.stat(abPath)
            if (statObj.isFile()) {
                this.fileHandle(req, res, abPath)
            } else {
                let directories = await fs.readdir(abPath)
                directories = directories.map(dir => {
                    let data = {
                        path: path.join(pathname, dir),
                        dir
                    }
                    return data
                })
                let parentPath = path.dirname(pathname)
                const promiseRenderFile = promisify(ejs.renderFile)
                let ret = await promiseRenderFile(
                    path.resolve(__dirname, 'template.html'),
                    { arr: directories, parent: pathname !== '/',parentPath}
                )
                res.end(ret)
            }
        } catch (err) {
            this.errorHandler(req, res, err)
        }
    }
    // 文件
    fileHandle(req, res, abPath) {
        res.statusCode = 200
        res.setHeader('content-type', mime.getType(abPath) + ';charset=utf8')
        createReadStream(abPath).pipe(res)
    }
    // 错误
    errorHandler(req, res, err) {
        res.statusCode = 404
        res.setHeader('content-type', 'text/html;charset=utf8')
        res.end('Not Found')
    }
}